package com.hqyj.springBoot.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@Aspect
@Component
public class MyAop {
    public static final Logger LOGGER = LoggerFactory.getLogger(MyAop.class);

    //设置切点方法

    //方法的全路径表达式，以任意方法的全路径来改造
    @Pointcut(value = "execution(public * com.hqyj.springBoot.modules.*.controller.*.*(..))")
    @Order(1)
    public void controllerCut(){}

    //环绕通知
    @Around(value = "controllerCut()")
    public Object aroundController(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        LOGGER.debug("=========== Around Controller ===========");
        return proceedingJoinPoint.proceed(proceedingJoinPoint.getArgs());
    }

    //前置通知
    @Before(value = "controllerCut()")
    public void beforeController(JoinPoint joinPoint){
        //用请求上下文的holder对象获取HttpServletRequest对象
        ServletRequestAttributes servletRequestAttributes =
                (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = servletRequestAttributes.getRequest();
        LOGGER.debug("=========== Before Controller ===========");
        LOGGER.debug(String.format("请求URL:%s",request.getRequestURL()));
        LOGGER.debug(String.format("请求Method:%s",request.getMethod()));
        LOGGER.debug(String.format("请求类:%s",joinPoint.getTarget().getClass().getName()));
        LOGGER.debug(String.format("请求方法:%s",joinPoint.getSignature().getName()));

    }

    //后置通知
    @After(value = "controllerCut()")
    public void afterController(JoinPoint joinPoint){
        LOGGER.debug("=========== After Controller ===========");

    }


    //注解切点，目标注解的全路径名
    @Pointcut("@annotation(com.hqyj.springBoot.aop.MyAnnotation)")
    @Order(1)
    public void annotationPointCut(){}


    //环绕通知
    @Around(value = "annotationPointCut()")
    public Object aroundAnnotation(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        LOGGER.debug("=========== Around Annotation ===========");
        long start = System.currentTimeMillis();
        Object result = proceedingJoinPoint.proceed(proceedingJoinPoint.getArgs());
        long end = System.currentTimeMillis();

        LOGGER.debug(String.format("调用方法耗时:%d",(end - start)));
        return result;
    }


}
